#include <sys/types.h>
#include <unistd.h>
#include <ctime>

#include "BlockQueue.hpp"
#include "Task.hpp"

const string oper = "+-*/%";    //运算符号
int mymath(int x,int y,char op)
{
    int result = 0;
    switch(op)
    {
        case '+':
            result = x + y;
            break;
        case '-':
            result = x - y;
            break;
        case '*':
            result = x * y;
            break;
        case '/':
        {
            if(y == 0)
            {
                cerr<<"div zero err" << endl;
                result = -1;
            }
            else 
                result = x / y;
            break;
        }
        case '%':
        {
            if(y == 0)
            {
                cerr<<"mod zero err" << endl;
                result = -1;
            }
            else 
                result = x % y;
            break;
        }
    }
    return result;
}
void* consumer(void* args)  //消费者线程
{
    BlockQueue<Task>* bq = static_cast<BlockQueue<Task>*>(args);
    while(true)
    {
        //消费活动
        
        Task t;
        bq->pop(&t);
        cout<<"消费任务：" << t() << endl;
        // sleep(1);
    }
    return nullptr;
}
void* productor(void* args) //生产者线程
{
    BlockQueue<Task>* bq = static_cast<BlockQueue<Task>*>(args);
    while(true)
    {
        //生产活动
        
        int x = rand()%10+1;
        int y = rand()%5;
        int operidx = rand()% oper.size();  //运算符下标

        Task t(x,y,oper[operidx],mymath);
        bq->push(t);

        cout<< "生产任务：" << t.to_Task_string() << endl;
        sleep(1);

    }
    return nullptr;
}
//单生产单消费
int main()
{
    srand((unsigned long)time(0) ^ getpid());
    BlockQueue<Task>* bq = new BlockQueue<Task>();
    pthread_t c,p;
    pthread_create(&c,nullptr,consumer,bq);
    pthread_create(&p,nullptr,productor,bq);

    pthread_join(c,nullptr);
    pthread_join(p,nullptr);

    delete bq;
    return 0;
}
//多生产多消费
// int main()
// {
//     srand((unsigned long)time(0) ^ getpid());

//     BlockQueue<Task>* bq = new BlockQueue<Task>();

//     pthread_t c[2],p[3];
//     pthread_create(p,nullptr,productor,bq);
//     pthread_create(p+1,nullptr,productor,bq);
//     pthread_create(p+2,nullptr,productor,bq);
//     pthread_create(c,nullptr,consumer,bq);
//     pthread_create(c+1,nullptr,consumer,bq);

//     pthread_join(c[0],nullptr);
//     pthread_join(c[1],nullptr);
//     pthread_join(p[0],nullptr);
//     pthread_join(p[1],nullptr);
//     pthread_join(p[2],nullptr);

//     delete bq;

//     return 0;
// }